import json
import re

from django import http
from django.conf import settings
from django.core.mail import send_mail
from django.shortcuts import render, redirect
from django.views import View
from django.views.decorators.csrf import csrf_exempt
from django_redis import get_redis_connection
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.mixins import LoginRequiredMixin


# Create your views here.


# 注册页面视图
from carts.utils import merge_cookie_redis_data
from celery_tasks.mail.task import send_verify_email
from meiduo_mall.utils.constants import *

from meiduo_mall.utils.my_encrypt import decode_verify_url, generate_verify_url
from meiduo_mall.utils.my_loginview import LoginRequiredView
from meiduo_mall.utils.response_code import RET
from users.models import User, Address


class RegisterView(View):

    def get(self, request):
        return render(request, 'register.html', context={'errmsg': ''})

    @csrf_exempt
    def post(self, request):
        # 1, 获取参数
        user_name = request.POST.get("user_name")
        pwd = request.POST.get("pwd")
        cpwd = request.POST.get("cpwd")
        phone = request.POST.get("phone")
        msg_code = request.POST.get("msg_code")
        allow = request.POST.get("allow")

        # 2, 校验参数
        # 2,1 为空校验
        if not all([user_name, pwd, cpwd, phone, msg_code, allow]):
            return http.HttpResponseForbidden("参数不全")

        # 2,2 两次密码一致
        if pwd != cpwd:
            return http.HttpResponseForbidden("两次密码不一致")

        # 2,3 手机号格式正确
        if not re.match(r'^1[3-9]\d{9}$',phone):
            return http.HttpResponseForbidden("手机号格式有误")

        # 2,5 短信验证码正确(下一次完成)
        redis_conn = get_redis_connection('code')
        redis_sms_code = redis_conn.get('sms_code_%s' % phone)
        if not redis_sms_code:

            return render(request, 'register.html', context={'code': RET.DBERR, 'errmsg': '验证码已过期'})
        if msg_code != redis_sms_code.decode():
            print("http.JsonResponse({'code': 4001, 'errmsg': '短信验证码错误'})")
            return render(request, 'register.html', context={'code': RET.DBERR, 'errmsg': '验证码错误'})

        # 2,6 协议需要同意
        if allow != 'on':
            return http.HttpResponseForbidden("协议需要同意")

        # 3, 数据入库
        # user = User.objects.create(username=user_name,password=pwd,mobile=phone)
        # 可以对密码加密
        user = User.objects.create_user(username=user_name, password=pwd, mobile=phone)
        login(request, user)
        response = redirect('/')
        response.set_cookie('username', user.username, max_age=REDIS_SESSION_COOKIE_EXPIRES)
        return response


class CheckUsernameView(View):

    def get(self, request, username):
        # 1, 根据用户名查询用户数量
        count = User.objects.filter(username=username).count()

        # 2, 返回响应
        return http.JsonResponse({"count": count, "code": RET.OK})


class CheckMobileView(View):

    def get(self, request, mobile):
        # 1, 根据手机号查询用户数量
        count = User.objects.filter(mobile=mobile).count()

        # 2, 返回响应
        return http.JsonResponse({"count": count, "code": RET.OK})


class LoginView(View):

    def get(self, request):
        return render(request, 'login.html', context={'loginerror': '', 'username': ''})

    @csrf_exempt
    def post(self, request):
        # 1,获取参数
        username = request.POST.get("username")
        pwd = request.POST.get("pwd")
        remembered = request.POST.get("remembered")

        # 2,校验参数
        # 2,1 为空校验
        if not all([username, pwd]):
            # return http.HttpResponseForbidden("参数不全")
            return render(request, 'login.html', context={'loginerror': '请输入用户名密码'})

        # # 2,2 用户名格式
        # if not re.match(r'^[a-zA-Z0-9_-]{5,20}$',username):
        #     return http.HttpResponseForbidden("用户名格式不对")
        #
        # # 2,3 密码格式校验
        # if not re.match(r'^[0-9A-Za-z]{8,20}$', pwd):
        #     return http.HttpResponseForbidden("密码格式不对")

        # 2,4账号密码正确校验
        user = authenticate(request=request, username=username, password=pwd)

        if not user:
            return render(request, 'login.html', context={'loginerror': '用户不存在或密码错误', 'username': username})

        # 3,数据入库
        login(request=request, user=user)  # 就是将用户的信息保存在session中
        if remembered == 'on':
            request.session.set_expiry(REDIS_SESSION_COOKIE_EXPIRES)
        else:
            request.session.set_expiry(0)

        # 4. 返回响应
        response = redirect('/')
        response.set_cookie('username', user.username, max_age=REDIS_SESSION_COOKIE_EXPIRES)
        # 合并购物车
        response = merge_cookie_redis_data(request, response)
        return response


# 用户中心
class UserInfoView(LoginRequiredView):

    def get(self, request):
        # 判断用户是否登录
        # if request.user.is_authenticated:
        #     return render(request, 'user_center_info.html')
        # return redirect('/login/')
        # 第二种继承LoginRequiredMixin
        # 拼接数据
        context = {
            'username': request.user.username,
            'mobile': request.user.mobile,
            'email': request.user.email,
            'email_active': request.user.email_active
        }
        return render(request, 'user_center_info.html', context=context)


class EmailView(LoginRequiredView):

    def put(self, request):

        email = json.loads(request.body.decode()).get('email')

        if not email:
            return http.JsonResponse({'code': RET.PARAMERR, 'errmsg': '参数不全'})

        # 数据入库,发送邮件
        verify_url = generate_verify_url(request.user, email)
        # result = send_mail(
        #     subject='商城验证链接',
        #     message='激活链接...' + verify_url,
        #     recipient_list=[email],
        #     from_email=settings.EMAIL_FROM
        # )
        #
        # print(result)
        #
        # if result != 1:
        #     return http.JsonResponse({'code': RET.THIRDERR, 'errmsg': '邮件发送失败'})

        # 使用celery发送邮件
        send_verify_email.delay(verify_url, email)
        print(verify_url)
        # 数据入库
        request.user.email = email
        request.user.save()

        return http.JsonResponse({'code': RET.OK, 'errmsg': '发送成功'})


class VerifyEmailView(LoginRequiredView):

    def get(self, request):
        token = request.GET.get('token')

        # 解密token
        user = decode_verify_url(token)
        print(user)
        if not user:
            return http.HttpResponseForbidden('token失效')

        user.email_active = True
        user.save()

        return redirect('/info')


class AddressesView(LoginRequiredView):
    def get(self, request):
        # 查询用户的地址
        addresses = request.user.addresses.filter(is_deleted=False).all()
        # 拼接数据
        addresses_list = [{"id": address.id,
                     "title": address.title,
                     "receiver":address.receiver,
                     "province": address.province.name,
                     "city": address.city.name,
                     "district": address.district.name,
                     "place": address.place,
                     "mobile": address.mobile,
                     "tel": address.tel,
                     "email": address.email,
                     "province_id": address.province_id,
                     "city_id": address.city_id,
                     "district_id": address.district_id,
                          } for address in addresses]
        context = {
            "addresses": addresses_list,
            "default_address_id": request.user.default_address_id if request.user.default_address_id else 0
        }
        # 渲染数据
        return render(request, 'user_center_site.html', context=context)


class AddressesCreateView(LoginRequiredView):


    def post(self, request):
        # 1,获取参数
        data_dict = json.loads(request.body.decode())
        title = data_dict.get("title")
        receiver = data_dict.get("receiver")
        province_id = data_dict.get("province_id")
        city_id = data_dict.get("city_id")
        district_id = data_dict.get("district_id")
        place = data_dict.get("place")
        mobile = data_dict.get("mobile")
        tel = data_dict.get("tel")
        email = data_dict.get("email")
        
        print(data_dict)
        
        # 2,校验参数
        if not all([title,receiver,province_id,city_id,district_id,place,mobile,tel,email]):
                return http.JsonResponse({"code":RET.PARAMERR,"errmsg":"参数不全"})
    
        
        data_dict['user_id'] = request.user.id
        address = Address.objects.create(**data_dict)
        
        # 4,返回响应
        data_dict = {
            "code":RET.OK,
            "address":{
                "id":address.id,
                "title":address.title,
                "receiver":address.receiver,
                "province":address.province.name,
                "city":address.city.name,
                "district":address.district.name,
                "place":address.place,
                "mobile":address.mobile,
                "tel":address.tel,
                "email":address.email,
                "province_id":address.province_id,
                "city_id":address.city_id,
                "district_id":address.district_id,
            }
        }
        return http.JsonResponse(data_dict)

    
# 10, 修改地址,删除地址
class AddressesUpdateView(LoginRequiredView):

    @csrf_exempt
    def put(self, request, address_id):
        # 1,获取参数
        address_id = int(address_id)
        data_dict = json.loads(request.body.decode())
        title = data_dict.get("title")
        receiver = data_dict.get("receiver")
        province_id = data_dict.get("province_id")
        city_id = data_dict.get("city_id")
        district_id = data_dict.get("district_id")
        place = data_dict.get("place")
        mobile = data_dict.get("mobile")
        tel = data_dict.get("tel")
        email = data_dict.get("email")
        
        print(data_dict)
        
        # 2,校验参数
        if not all([title,receiver,province_id,city_id,district_id,place,mobile,tel,email]):
                return http.JsonResponse({"code":RET.PARAMERR,"errmsg":"参数不全"})

        # 3,数据入库,返回的数据是整数,表示修改的行数
        try:
            del data_dict["id"]
            del data_dict["province"]
            del data_dict["city"]
            del data_dict["district"]
            ret = Address.objects.filter(id=address_id).update(**data_dict)
            address = Address.objects.get(id=address_id)
        except Exception as e:
            print(e)
            print(data_dict)
            return http.JsonResponse({"code": RET.DATAERR, "errmsg": "修改失败"})

        # 4,返回响应
        data_dict = {
            "code":RET.OK,
            "address":{
                "id":address.id,
                "title":address.title,
                "receiver":address.receiver,
                "province":address.province.name,
                "city":address.city.name,
                "district":address.district.name,
                "place":address.place,
                "mobile":address.mobile,
                "tel":address.tel,
                "email":address.email,
                "province_id":address.province_id,
                "city_id":address.city_id,
                "district_id":address.district_id,
            }
        }
        return http.JsonResponse(data_dict)

    def delete(self,request,address_id):
        # 1,数据入库
        try:
            ret = Address.objects.filter(id=address_id).update(is_deleted=True)
            print(ret)
        except Exception as e:
            print(e)
            return http.JsonResponse({"code":RET.DBERR,"errmsg":"删除失败"})

        # 2,返回响应
        return http.JsonResponse({"code": RET.OK, "errmsg": "删除成功"})
    
    
class AddressesDefaultView(LoginRequiredView):

    @csrf_exempt
    def put(self, request, address_id):
        try:
            request.user.default_address_id = address_id
            request.user.save()
        except Exception as e:
            print(e)
            return http.JsonResponse({"code":RET.DBERR,"errmsg":"设置默认失败"})
        
        return http.JsonResponse({"code":RET.OK,"errmsg":"修改成功"})
    

class AddressesTitleView(LoginRequiredView):
    @csrf_exempt
    def put(self,request,address_id):
        #1,获取参数
        title = json.loads(request.body.decode()).get("title")

        #2,校验参数
        if not title:
            return http.JsonResponse({"code":RET.PARAMERR,"errmsg":"参数不全"})

        #3,数据入库
        try:
            Address.objects.filter(id=address_id).update(title=title)
        except Exception as e:
            return http.JsonResponse({"code": RET.DBERR, "errmsg": "修改失败"})

        #4,返回响应
        return http.JsonResponse({"code": RET.OK, "errmsg": "修改成功"})
    

class UserPassWordView(LoginRequiredView):
    def get(self, request):
        return render(request, 'user_center_pass.html')

    @csrf_exempt
    def post(self, request):
        old_pwd = request.POST.get('old_pwd')
        new_pwd = request.POST.get('new_pwd')
        new_cpwd = request.POST.get('new_cpwd')
        
        if not all([old_pwd, new_pwd, new_cpwd]):
            return render(request, 'user_center_pass.html', context={'errmsg', '参数不去'})
        
        if not request.user.check_password(old_pwd):
            return render(request, 'user_center_pass.html', context={'errmsg': '原密码错'})
        
        if old_pwd == new_pwd:
            return render(request, 'user_center_pass.html')
        
        if new_pwd != new_cpwd:
            return render(request, 'user_center_pass.html')
        
        request.user.set_password(new_pwd)
        
        request.user.save()
        
        response = redirect('/login')
        logout(request)
        response.delete_cookie('username')
        
        return response
        
        
        
        
        
        
        
        
